package com.duoduo.springboot.security.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.CollectionUtils;
import org.springframework.util.PathMatcher;

import com.duoduo.springboot.security.vo.PermissionVO;
import com.duoduo.springboot.security.vo.RoleVO;

@Service
public class SecurityCache {

	private static Map<String, Collection<ConfigAttribute>> resourceMap = null;
	private PathMatcher pathMatcher = new AntPathMatcher();

	@Resource
	private RoleService roleService;
	@Resource
	private PermissionService permissionService;

	public void loadResourceDefine() {
		resourceMap = new LinkedHashMap<String, Collection<ConfigAttribute>>();

		List<RoleVO> roles = roleService.listAll();
		if (!CollectionUtils.isEmpty(roles)) {
			for (RoleVO role : roles) {
				updateByRole(role.getId());
			}
		}

		// 其他权限
		Collection<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
		list.add(new SecurityConfig("0"));
		resourceMap.put("/", list);
		resourceMap.put("/**", list);
	}

	public boolean updateByRole(int roleId) {
		List<PermissionVO> permissions = permissionService.listPermissionsByRoleId(roleId);
		if (!CollectionUtils.isEmpty(permissions)) {
			for (PermissionVO resource : permissions) {
				String url = resource.getUrl();
				if (StringUtils.isBlank(url)) {
					continue;
				}

				Collection<ConfigAttribute> configAttributes = null;
				ConfigAttribute configAttribute = new SecurityConfig("" + roleId);
				if (resourceMap.containsKey(url)) {
					configAttributes = resourceMap.get(url);
					configAttributes.add(configAttribute);
				} else {
					configAttributes = new ArrayList<ConfigAttribute>();
					configAttributes.add(configAttribute);
					resourceMap.put(url, configAttributes);
				}
			}
		}
		return true;
	}

	public boolean updateByResource() {
		loadResourceDefine();
		return true;
	}

	public Collection<ConfigAttribute> getAllConfigAttributes() {
		if (CollectionUtils.isEmpty(resourceMap)) {
			loadResourceDefine();
		}

		Collection<ConfigAttribute> list = new ArrayList<ConfigAttribute>();
		for (Collection<ConfigAttribute> caList : resourceMap.values()) {
			for (ConfigAttribute ca : caList) {
				if (!list.contains(ca)) {
					list.add(ca);
				}
			}
		}

		return list;
	}

	public Collection<ConfigAttribute> getAttributes(String url) {
		if (StringUtils.isNotBlank(url)) {
			for (String resUrl : resourceMap.keySet()) {
				// 注：resourceMap为LinkedHashMap，是有顺序的
				// PS：resourceMap所有的资源都是标准的url，这里不需处理，直接匹配即可
				if (pathMatcher.match(resUrl, url)) {
					return resourceMap.get(resUrl);
				}
			}
		}

		return null;
	}
}
